using System.Text;
using System.Collections.Generic;
using System.IO;
using Framework;
using UnityEngine;
using UnityEditorInternal;
using UnityEditor;
using UnityEngine.UI;
using System.Text.RegularExpressions;

namespace Framework
{

    public class UGUIProcessorBase
    {
        //生成代码
        protected string _outPathFormat = Path.Combine(Application.dataPath, "Game/Scripts/GUI/{0}.cs");
        //变量代码
        protected string _fieldsOutPathFormat = Path.Combine(Application.dataPath, "Game/Scripts/Generate/UI/{0}.Fields.cs");
        //路径代码
        protected string _infoPath = Path.Combine(Application.dataPath, "Game/Scripts/Generate/UI/GUIPathInfo.cs");
        //层级提示
        protected string[] _layers;

        private bool compile;
        public string GetBindClassPath(string name)
        {
            return name;
        }

        public string[] GetLayerNames()
        {
            if (_layers == null)
            {
                _layers = new string[] { "Base", "Float", "Pop", "Tip" };
            }
            return _layers;
        }

        public void OpenCodeFile(UGUIWidget value)
        {

            var output = string.Format(_outPathFormat, getClassName(value));
            if (!File.Exists(output)) return;
            InternalEditorUtility.OpenFileAtLineExternal(output, 0);
        }
        public void CreateCodeFile(UGUIWidget value)
        {
            if (!createCode(value))
            {
                return;
            }
            createFieldsCode(value);
            var path = Utils.Unity.GetAssetPath(value.gameObject);
            if (!string.IsNullOrEmpty(path))
            {
                var dir = Path.GetDirectoryName(_infoPath);
                if (!Directory.Exists(dir))
                {
                    Directory.CreateDirectory(dir);
                }
                if (!File.Exists(_infoPath))
                {
                    var tmp = @"using Framework;
public sealed class GUIPathInfo
{
}";
                    File.WriteAllText(_infoPath, tmp);
                }
                if (value is UGUIWindow window)
                {
                    //window.CodePath
                    var list = new List<string>();
                    list.AddRange(File.ReadAllLines(_infoPath));
                    var len = list.Count;
                    var exist = false;

                    var search = GetItemCode(window, path);
                    if(!MatchItemCode(list, path))
                    {
                        list.Insert(list.Count - 1, "\t" + search);
                        File.WriteAllLines(_infoPath, list);
                        AssetDatabase.Refresh();
                        UnityEditor.Compilation.CompilationPipeline.RequestScriptCompilation();
                    }
                    while (len-- > 0)
                    {
                        var line = list[len];
                        if (line.IndexOf(search) != -1)
                        {
                            exist = true;
                            break;
                        }
                    }
                    if (!exist)
                    {
                        
                    }
                }
            }
            if (compile)
            {
                compile = false;
                // AssetDatabase.Refresh();
                UnityEditor.Compilation.CompilationPipeline.RequestScriptCompilation();
            }
            Debug.LogWarning("success " + value.CodePath);
        }
        protected virtual string GetItemCode(UGUIWindow window, string path)
        {
            //public UIWindowInfo LoginUI = new UIWindowInfo() { Path = "Assets/Res/GUI/LoginUI.prefab", Logic = typeof(LoginUI) };
            var name = getClassName(window);
            return "public UIWindowInfo " + name + " = new UIWindowInfo() { Path = \"" + path + "\", Logic = typeof(" + name + ") };";
        }
        protected virtual bool MatchItemCode(List<string> lines, string path)
        {
            foreach (var line in lines)
            {
                if(line.Contains(path))
                {
                    return true;
                }
            }

            return false;
        }
        protected virtual  string getClassName(UGUIWidget value)
        {
            string name = Utils.Text.FirstCharUpper(value.CodePath);
            bool isValid = Regex.IsMatch(name, @"^[A-Z][a-zA-Z0-9_]*$");
            if (isValid)
            {
                return name;
            }
            Debug.LogErrorFormat("类名不合法 {0}", value.CodePath);
            return string.Empty;
        }
        protected virtual  bool createCode(UGUIWidget value)
        {
            var className = getClassName(value);
            if (string.IsNullOrEmpty(className))
            {
                return false;
            }
            var output = string.Format(_outPathFormat, getClassName(value));
            if (File.Exists(output))
            {
                return true;
            }
            var s = @"
using Framework;
using UnityEngine;
using UnityEngine.UI;
public partial class _N_ : _B_
{
    
}";
            s = s.Replace("_N_", getClassName(value));
            if (value is UGUIWindow)
            {
                s = s.Replace("_B_", "UIWindowBase");
            }
            else
            {
                s = s.Replace("_B_", "UIWidgetBase");
            }
            var dir = Path.GetDirectoryName(output);
            if (!Directory.Exists(dir))
            {
                Directory.CreateDirectory(dir);
            }
            File.WriteAllText(output, s);
            compile = true;
            return true;
        }
        protected virtual  void createFieldsCode(UGUIWidget value)
        {
            var fieldObj = value.GetComponent<GameObjectFields>();
            if (fieldObj == null) return;
            fieldObj.Check(true);
            var flist = fieldObj.BuildScriptFields();
            var plist = fieldObj.BuildScriptParse();
            var output = string.Format(_fieldsOutPathFormat, getClassName(value));
            var s = @"
//自动生成
using Framework;
using UnityEngine;
using UnityEngine.UI;
public partial class _N_
{
_F_
    protected override void InjectFields(GameObjectFields value)
    {
_P_
    }
}
";
            s = s.Replace("_N_", getClassName(value));

            StringBuilder builder = new StringBuilder();
            foreach (var item in flist)
            {
                builder.Append("\t");
                builder.AppendLine(item);
            }

            s = s.Replace("_F_", builder.ToString());
            builder.Clear();
            foreach (var item in plist)
            {
                builder.Append("\t\t");
                builder.AppendLine(item);
            }
            var btn = "\t\tthis._N_.onClick.AddListener(() => { this.OnButtonClick(this._N_); });";
            foreach (var item in fieldObj.FieldItems)
            {
                if (item.Type == typeof(Button).FullName)
                {
                    builder.Append(btn.Replace("_N_", item.GetFieldName()));
                    builder.AppendLine();
                }
            }
            s = s.Replace("_P_", builder.ToString());
            var dir = Path.GetDirectoryName(output);
            if (!Directory.Exists(dir))
            {
                Directory.CreateDirectory(dir);
            }
            string nowContent = string.Empty;
            if (File.Exists(output))
            {
                nowContent = File.ReadAllText(output);
            }
            if (nowContent == s) return;
            File.WriteAllText(output, s);
            compile = true;

        }
    }
}